package model;
import java.awt.Color;
import java.util.List;
import java.util.Iterator;
import interfaces.*;

/**
 * A model of Falcon
 * Falcons age, move, breed, and die.
 * 
 * @author Stephan Veenstra, Marc Bruins, Michel Jansma
 * @version 1.0
 */

public class Falcon extends Animal
{
	// Characteristics shared by all falcons (static fields).
    
	//Falcon color
	public static Color COLOR = Color.GRAY;
    // The age at which a falcon can start to breed.
    private static final int BREEDING_AGE = 10;
    // The age to which a falcon can live.
    private static final int MAX_AGE = 150;
    // The likelihood of a falcon breeding.
    private static final double BREEDING_PROBABILITY = 0.35;
    // The maximum number of births.
    private static final int MAX_LITTER_SIZE = 5;
    // The food value of a single rabbit. In effect, this is the
    // number of steps a falcon can go before it has to eat again.
    private static final int RABBIT_FOOD_VALUE = 7;
    
    // Individual characteristics (instance fields).
    
    // The Falcon's food level, which is increased by eating.
    private int foodLevel;
    
    /**
     * Create a falcon. A falcon can be created as a new born (age zero
     * and not hungry) or with a random age and food level.
     * 
     * @param randomAge If true, the fox will have random age and hunger level.
     * @param field The field currently occupied.
     * @param location The location within the field.
     */
    public Falcon(boolean randomAge, Field field, Location location)
    {
        super(randomAge, field, location);
        if(randomAge) {
            foodLevel = rand.nextInt(RABBIT_FOOD_VALUE);
        }
        else {
            foodLevel = RABBIT_FOOD_VALUE;
        }
    }
    
    /**
     * This is what the falcon does most of the time: it hunts for
     * rabbits. In the process, it might breed, die of hunger,
     * or die of old age.
     * @param field The field currently occupied.
     * @param newFalcons A list to add newly born falcons to.
     */
    @Override
    public void act(List<Actor> newFalcons)
    {
        incrementAge();
        incrementHunger();
        if(isActive()) {
            giveBirth(newFalcons);            
            // Move towards a source of food if found.
            Location location = getLocation();
            Location newLocation = findFood(location);
            if(newLocation == null) { 
                // No food found - try to move to a free location.
                newLocation = getField().freeAdjacentLocation(location);
            }
            // See if it was possible to move.
            if(newLocation != null) {
                setLocation(newLocation);
            }
            else {
                // Overcrowding.
                setDead();
            }
        }
    }
    
    /**
     * Make this facons more hungry. This could result in the falcons's death.
     */
    private void incrementHunger()
    {
        foodLevel--;
        if(foodLevel <= 0) {
            setDead();
        }
    }
    
    /**
     * Tell the falcon to look for rabbits adjacent to its current location.
     * Only the first live rabbit is eaten.
     * @param location Where in the field it is located.
     * @return Where food was found, or null if it wasn't.
     */
    private Location findFood(Location location)
    {
        Field field = getField();
        List<Location> adjacent = field.adjacentLocations(getLocation());
        Iterator<Location> it = adjacent.iterator();
        while(it.hasNext()) {
            Location where = it.next();
            Object animal = field.getObjectAt(where);
            if(animal instanceof Rabbit) {
                Rabbit rabbit = (Rabbit) animal;
                if(rabbit.isActive()) { 
                    rabbit.setDead();
                    foodLevel = RABBIT_FOOD_VALUE;
                    // Remove the dead rabbit from the field.
                    return where;
                }
            }
        }
        return null;
    }
    
    
    /**
     * An animal can breed if it has reached the breeding age.
     * @return true if the anmial can breed, false otherwise.
     */
    public boolean canBreed()
    {
    	return getAge() >= BREEDING_AGE;
    }
     
    /**
     * Return the MAX_AGE of the falcon.
     */
    protected int getMaxAge()
    {
    	return MAX_AGE;
    }
    
    /**
     * Returns the BREEDING_AGE of the falcon
     */
    protected int getBreedingAge()
    {
    	return BREEDING_AGE;
    }
    
    /**
     * Returns the BREEDING_PROBABILITY of the falcon
     */
    protected double getBreedingProbability()
    {
    	return BREEDING_PROBABILITY;
    }
    
    /**
     * returns the MAX_LITTER_SIZE of the falcon
     */
    protected int getMaxLitterSize()
    {
    	return MAX_LITTER_SIZE;
    }
}
